#include "app_clock.h"
#include "app_timer.h"
#include <string.h>

#define APP_TIMER_PRESCALER             0
#define TIMER_1S_INTERVAL               APP_TIMER_TICKS(1000,APP_TIMER_PRESCALER)

#define IS_LEAP_YEAR(yr) (!((yr) % 400) || (((yr) % 100) && !((yr) % 4)))
#define IS_BIG_MONTH(mon) (mon == 1 || mon == 3 || mon == 5 || mon == 7 || mon == 8 || mon == 10 || mon == 12 )
#define IS_NOT_LAST_DAY_OF_MONTH() \
        ( ((System_dtime.month == 2) && \
            ((System_dtime.day < 28 && !(IS_LEAP_YEAR(System_dtime.year)) ) || \
                (System_dtime.day < 29 && IS_LEAP_YEAR(System_dtime.year) )) ) || ((System_dtime.month != 2) && \
        ((System_dtime.day < 30 && !(IS_BIG_MONTH(System_dtime.month))) || \
        (System_dtime.day < 31 && IS_BIG_MONTH(System_dtime.month)) )))

clock_time_t   System_dtime;
static uint32_t system_on_time = 0;
APP_TIMER_DEF(m_timer_1s_id);


static void clock_cb_call(uint8_t flag)
{
////    uint32_t err;
////    err = app_sched_event_put(&flag, sizeof(uint8_t), clock_cb_call_handle);
////    APP_ERROR_CHECK(err);
}

/* 过24点 增加一天 */
static void add_day(void) 
{
    if (IS_NOT_LAST_DAY_OF_MONTH()) {
        System_dtime.day++;
    } else {
        System_dtime.day = 1;
        if (System_dtime.month < 12) {
            System_dtime.month++;
        } else {
            System_dtime.month = 1;
            System_dtime.year++;
        }
    }
    if (System_dtime.day_of_week < 6) {
        System_dtime.day_of_week++;
    } else {
        System_dtime.day_of_week = 0;
    }
}


/* 1s 定时器事件 */
static void timer_1s_handle(void * p_contex)
{
    system_on_time ++;
    if (System_dtime.second < 59) {
        System_dtime.second++;  
        clock_cb_call(CLOCK_CB_FLAG_1SECOND);
    }
    else 
    {
        System_dtime.second = 0;
        clock_cb_call(CLOCK_CB_FLAG_1SECOND);
        if (System_dtime.minute < 59) {
            System_dtime.minute++;          
        }
        else
        {
            System_dtime.minute = 0;
            if (System_dtime.hour < 23)
            {
                System_dtime.hour++;
            }
            else
            {
                System_dtime.hour = 0;
                add_day();
                clock_cb_call(CLOCK_CB_FLAG_1DAY);
            }
        }  
        clock_cb_call(CLOCK_CB_FLAG_1MINUTE);
    }
    return ;
}

uint8_t User_clock_init(void)
{
    uint8_t  i;
    uint32_t err_code;

    System_dtime.year       = 2020;
    System_dtime.month      = 1;
    System_dtime.day        = 1;
    System_dtime.hour       = 0;
    System_dtime.minute     = 0;
    System_dtime.second     = 0;
    //User_clock_seconds = System_dtime.hour * 60 * 60 + System_dtime.minute * 60 + System_dtime.second;
    System_dtime.day_of_week = 3;


////    for(i = 0; i < CLOCK_1SECOND_CB_MAX; i++ ) {
////        clock_1second_cbs[i] = NULL;
////    }
////    for(i = 0; i < CLOCK_1MINUTE_CB_MAX; i++ ) {
////        clock_1minute_cbs[i] = NULL;
////    }

////    for(i = 0; i < CLOCK_1DAY_CB_MAX; i++ ) {
////        clock_1day_cbs[i] = NULL;
////    }
    
    // Create timers 1s
    err_code = app_timer_create(&m_timer_1s_id, APP_TIMER_MODE_REPEATED, timer_1s_handle);
    APP_ERROR_CHECK(err_code);
    err_code = app_timer_start(m_timer_1s_id, TIMER_1S_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);

    return CLOCK_SUCCESS;
}

clock_time_t* Get_Clock_time(void)
{
    return &System_dtime;
}

void Set_Clock_time(clock_time_t* p_time)
{
    memcpy(&System_dtime,p_time,sizeof(clock_time_t));
}
